#include <gdt.h>
#include <ecrantexte.h>
#include <assembleur.h>

GDT::GDT()
{
  int i, j;

  dernierDescripteur = 0;
  for(i=0;i<256;i++)
  {
    for(j=0;i<8;i++)
    {
      gdt[i][j] = (char)0;
    }
  }
}

unsigned char GDT::AjouterDescripteur(int base, int limite, unsigned short parametres)
{
  if(RecupererPlaceRestante() <= 0)
  {
    return (unsigned char)0;
  }

  dernierDescripteur++;

  gdt[dernierDescripteur][0] = ((base & 0xFFFF) << 16) + (limite & 0xFFFF);

  gdt[dernierDescripteur][1] = ((base & 0xFF0000) >> 16) + (base & 0xFF000000);
  gdt[dernierDescripteur][1] += ((parametres & 0xF0FF) << 8) + (limite & 0x000F0000);

  return (dernierDescripteur << 3);
}

int GDT::RecupererPlaceRestante()
{
  return (0xFF - dernierDescripteur);
}

void GDT::ChargerGDTR()
{
  sChargerGDTR(gdt, 256*8);
}

void GDT::RemplacerDescripteur(unsigned char descripteur, int base, int limite, unsigned short parametres)
{
  int sauvegardededernierdescripteur = dernierDescripteur;

  dernierDescripteur = descripteur - 1;
  AjouterDescripteur(base, limite, parametres);

  dernierDescripteur = sauvegardededernierdescripteur;
}

/***********************************************/

int TestGDT::Test(EcranTexte* ecrantemporaire)
{
  int testreussi = 1;

  if(AjoutDUnDescripteur() == 0)
  {
    ecrantemporaire->Ecrire("Test d'ajout d'un descripteur a la GDT rate.\n");
    testreussi = 0;
  }
  else if(AjoutDUnDescripteur_PlusDePlace() == 0)
  {
    ecrantemporaire->Ecrire("Test de rejet d'ajout d'un 257eme descripteur a la GDT rate.\n");
    testreussi = 0;
  }
  else if(RemplacementDUnDescripteur() == 0)
  {
    ecrantemporaire->Ecrire("Test de remplacement d'un descripteur dans la GDT rate.\n");
    testreussi = 0;
  }

  return testreussi;
}

int TestGDT::AjoutDUnDescripteur()
{
  int selecteurdesegment;

  dernierDescripteur = 0;
  selecteurdesegment = AjouterDescripteur(0x11223344, 0x55667788, 0x99AA);

  if(selecteurdesegment != 0x8)
  {
    return 0;
  }
  else if(gdt[1][0] != 0x33447788 || gdt[1][1] != 0x1196AA22)
  {
    return 0;
  }
  else
  {
    return 1;
  }
}

int TestGDT::AjoutDUnDescripteur_PlusDePlace()
{
  int selecteurdesegment;

  dernierDescripteur = 0xFF;
  selecteurdesegment = AjouterDescripteur(0, 0xFFFFF, 0xFFFF);

  if(selecteurdesegment != 0)
  {
    return 0;
  }
  else
  {
    return 1;
  }
}

int TestGDT::RemplacementDUnDescripteur()
{
  RemplacerDescripteur(0x11, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAA);

  if(gdt[0x11][0] == 0xAAAAAAAA && gdt[0x11][1] == 0xAAAAAAAA)
  {
    return 1;
  }
  else
  {
    return 0;
  }
}
